// gen-api.js
const fs   = require('fs');
const path = require('path');

const raw  = fs.readFileSync('./java-swagger.json','utf-8');
const doc  = JSON.parse(raw);

/* ---------- 工具 ---------- */
function pascal(str){
  if(!str) return '';
  return str
    .replace(/[-_./\s]+(.)?/g,(_,c)=>(c?c.toUpperCase():''))
    .replace(/^./,c=>c.toUpperCase());
}

function mapType(t){
  const m={integer:'number',int32:'number',int64:'number',double:'number',float:'number'};
  return m[t]||t;
}

/* ---------- 全局缓存已生成的实体 interface ---------- */
const generatedSet=new Set(); // 只存最里层实体名
let topIfc='';               // 将拼接到文件最顶部

/* ---------- 递归生成实体 interface ---------- */
function buildEntityIfc(name,schema){
  if(generatedSet.has(name)) return;
  generatedSet.add(name);

  let buf=`export interface ${name} {\n`;
  Object.entries(schema.properties||{}).forEach(([key,prop])=>{
    const ty=mapType(prop.type);
    const opt=schema.required?.includes(key)?'':'?';
    const desc=prop.description?`  /** ${prop.description} */\n`:'';
    buf+=desc+`  ${key}${opt}: ${ty};\n`;
  });
  buf+=`}\n\n`;
  topIfc=buf+topIfc; // 往前插，保持依赖顺序
}

/* ---------- 主流程 ---------- */
const tagMap={}; // { tag:[...ops] }

Object.entries(doc.paths).forEach(([url,pathItem])=>{
  Object.entries(pathItem).forEach(([method,op])=>{
    const tag=(op.tags&&op.tags[0])||'Default';
    tagMap[tag]=tagMap[tag]||[];
    tagMap[tag].push({url,method,op});
  });
});

/* ---------- 安全提取 List«A» 的 items.$ref ---------- */
function extractListItemRef(ref) {
  if (!ref) return null;
  const key = ref.split('/').pop();               // R«List«UserEntity»» | List«UserEntity»
  const schema = doc.components.schemas[key];
  if (!schema) return null;
  if (schema.type === 'array' && schema.items && schema.items.$ref) {
    return schema.items.$ref;                     // #/components/schemas/UserEntity
  }
  return null;
}

// 拿到最里层实体名（去掉 R/List 等外壳）
function cleanRef(ref) {
  if (!ref) return 'any';
  const last = ref.split('/').pop();               // R«List«UserEntity»»
  const inner = last.replace(/[«»]/g, '');        // RListUserEntity
  return inner.replace(/^R/, '')                   // ListUserEntity
              .replace(/^List/, '');               // UserEntity
}

// 解析响应类型：List«A» → A[]，否则 → A
function resolveRespType(ref) {
  if (!ref) return 'any';
  const last = ref.split('/').pop();               // R«List«UserEntity»»
  const inner = last.replace(/[«»]/g, '');        // RListUserEntity
  const stripped = inner.replace(/^R/, '');        // ListUserEntity
  if (stripped.startsWith('List')) {               // List«A» 形式
    const entity = stripped.replace(/^List/, '');  // UserEntity
    return `${entity}[]`;
  }
  return stripped;                                 // 单个实体
}

/* ---------- 提前扫描：生成所有实体 interface ---------- */
Object.entries(doc.paths).forEach(([url, pathItem]) => {
  Object.entries(pathItem).forEach(([method, op]) => {
    const { responses, requestBody, parameters = [], operationId } = op;

    /* 1. 响应 200 */
    const ok200 = responses?.[200];
    const ref = ok200?.content?.['*/*']?.schema?.$ref;
    if (ref) {
      if (ref.includes('List«')) {                          // 列表场景
        const itemsRef = extractListItemRef(ref);
        if (itemsRef) {
          const entityName = cleanRef(itemsRef);
          const sch = doc.components.schemas[itemsRef.split('/').pop()];
          if (sch) buildEntityIfc(entityName, sch);
        }
      } else {                                              // 单个实体
        const name = cleanRef(ref);
        const sch = doc.components.schemas[ref.split('/').pop().replace(/[«»]/g, '')];
        if (sch) buildEntityIfc(name, sch);
      }
    }

    /* 2. PUT 请求体 */
    if (method === 'put' && requestBody) {
      const bodyRef = requestBody.content["application/json"].schema.$ref;
      const sch = doc.components.schemas[bodyRef.split('/').pop()];
      const name = cleanRef(bodyRef);
      if (sch) buildEntityIfc(name, sch);
    }

    if (method === 'post' && parameters.length) {
      const name = pascal(operationId) + 'Input';
      if (!generatedSet.has(name)) {
        generatedSet.add(name);
        let buf = `export interface ${name} {\n`;
        parameters.forEach(p => {
          const desc = p.description ? `  /** ${p.description}${p.required ? '（必填）' : '（可选）'} */\n` : '';
          const opt  = p.required ? '' : '?';
          const ty   = mapType(p.schema.type);
          buf += `${desc}  ${p.name}${opt}: ${ty};\n`;
        });
        buf += `}\n\n`;
        topIfc = buf + topIfc;
      }
    }

  });
});

/* ---------- 输出文件 ---------- */
const date = new Date();
let ts=`/* ${doc.info.title} */\n`;
ts+=`/* ${doc.info.description} */\n`;
ts+=`/* ${doc.info.version} */\n`;
ts+=`/* 生成时间: ${date.getFullYear()}-${date.getMonth() + 1}-${date.getDay()} ${date.getHours()}:${date.getMinutes()}:${date.getSeconds()} */\n\n`
ts+=`import { defHttp, RequestOptions } from '@/utils/http';\n\n`;
ts+=topIfc; // 所有实体 interface 已经按依赖顺序拼在前面

Object.entries(tagMap).forEach(([tag,ops])=>{
  const clsName=pascal(tag)+'Client';
  ts+=`export class ${clsName} {\n`;

  ops.forEach(({url,method,op})=>{
    const {
      operationId,
      summary,
      parameters=[],
      requestBody,
      responses:{200:ok200}
    }=op;

    /* ---- 响应类型 ---- */
    const respRef=ok200?.content?.['*/*']?.schema?.$ref;
    let respType='any';
    if(respRef){
      if(respRef.includes('List«')){
        const itemsRef=ok200.content['*/*'].schema.$ref;
        const entityName=cleanRef(doc.components.schemas[itemsRef.split('/').pop()].title);
        respType=resolveRespType(entityName);
      }else{
        respType=cleanRef(respRef);
      }
    }

    /* ---- 方法形参 ---- */
    let args=[];
    if(method==='put'){
      const bodyRef=requestBody.content['application/json'].schema.$ref;
      const name=cleanRef(bodyRef);
      args.push(`input: ${name}`);
    }else if(method==='post'&&parameters.length){
      const name=pascal(operationId)+'Input';
      args.push(`input: ${name}`);
    }else if(method==='get'||method==='delete'){
      const pathParams=[],queryParams=[];
      parameters.forEach(p=>{
        if(url.includes(`{${p.name}}`)) pathParams.push(p);
        else queryParams.push(p);
      });
      [...pathParams,...queryParams].forEach(p=>{
        args.push(`${p.name}${p.required?'':'?'}: ${mapType(p.schema.type)}`);
      });
    }
    args.push('options?: RequestOptions');

    /* ---- 函数名 ---- */
    const funcName=pascal(operationId);

    /* ---- 调用 ---- */
    ts+=`\n  /** ${summary||''} */\n`;
    ts+=`  ${funcName}(${args.join(', ')}){\n`;

    const tpl='`'+url.replace(/{([^}]+)}/g,'${$1}')+'`';

    if(method==='get'||method==='delete'){
      const q=parameters.filter(p=>!url.includes(`{${p.name}}`));
      const query=q.length?'{ '+q.map(p=>p.name).join(', ')+' }':'{}';
      ts+=`    return defHttp.${method}<${respType}>({ url:${tpl}, params:${query} }, options);\n`;
    }else if(method==='post'){
      ts+=`    return defHttp.post<${respType}>({ url:${tpl}, data:input }, options);\n`;
    }else if(method==='put'){
      ts+=`    return defHttp.put<${respType}>({ url:${tpl}, data:input }, options);\n`;
    }

    ts+=`  }\n`;
  });

  ts+=`}\n\n`;
  
  ts += `const ${clsName.slice(0, 1).toLowerCase() + clsName.slice(1)} = new ${clsName}();\n`;
  ts += `export default { ${clsName.slice(0, 1).toLowerCase() + clsName.slice(1)} };\n`;
});



fs.writeFileSync(path.join(__dirname,'api.ts'),ts);
console.log('✅ api.ts 已生成');